#include <stdio.h>

int Add(int *array, int n)
{
  int t = 0, i = 0;

  for(i=0; i < n; ++i) 
	  t += array[i];

  return t;
}

int main() 
{
  static int num = 10;
  int a[5] = {1, 2, 3, 4, 5 };

  int sum = Add(a, 5);

  sum = sum + num;

  return sum;
}


#if 0

0000000000400710 <_Z3AddPii>:

  400710: 	push   %rbp             // 将 rbp 的值压入栈中，保存上一个栈帧地址
  400711: 	mov    %rsp,%rbp        // 将 rbp 赋值为 rsp，设置main函数的栈帧基址
  400714: 	mov    %rdi,-0x18(%rbp) // 将两个参数放到栈上
  400718: 	mov    %esi,-0x1c(%rbp)
  40071b: 	movl   $0x0,-0x4(%rbp)  // 在栈上初始化变量 t 为 0
  400722: 	movl   $0x0,-0x8(%rbp)         // 在栈上初始化变量 i 为 0
  400729: 	jmp    400748 <_Z3AddPii+0x38> // 跳转到地址 400748 处
  40072b: 	mov    -0x8(%rbp),%eax         // 将变量 i 放到 eax 中
  40072e: 	cltq   
  400730: 	lea    0x0(,%rax,4),%rdx       // rdx = rax * 4，因为 eax 是 rax 的低32位，eax的值是变量 i，所以这里 rdx = i * 4
  400737:
  400738: 	mov    -0x18(%rbp),%rax         // 将第一个参数数组 array 的地址放到 rax
  40073c: 	add    %rdx,%rax                // 加上地址偏移 rdx
  40073f: 	mov    (%rax),%eax              // 将 rax 中的地址所指向的值放到 eax 中，取数组中的元素
  400741: 	add    %eax,-0x4(%rbp)          // 将变量 t 加上 eax 中的值并放在 t 上
  400744: 	addl   $0x1,-0x8(%rbp)          // 将变量 i 加 1 
  400748: 	mov    -0x8(%rbp),%eax          // 将变量 i 放到 eax 中
  40074b: 	cmp    -0x1c(%rbp),%eax         // 比较变量 i 和传递进来的第二个参数 5 
  40074e: 	jl     40072b <_Z3AddPii+0x1b>  // 如果小于，则跳转到地址 40072b 处
  400750: 	mov    -0x4(%rbp),%eax          // 将返回值 t 放到 eax
  400753: 	pop    %rbp                     // 从栈中弹出上一个栈帧的值到 rbp
  400754: 	retq                            // 函数返回，retq指令会从栈中弹出返回地址到指令指针寄存器 rip 中

0000000000400755 <main>:

  400755: 	push   %rbp             // 将 rbp 的值压入栈中，保存上一个栈帧地址
  400756: 	mov    %rsp,%rbp        // 将 rbp 赋值为 rsp，设置main函数的栈帧基址
  400759: 	sub    $0x20,%rsp       // 将 rsp 的值减去 0x20，使 rsp 下移到 rbp - 0x20 的位置，分配栈空间
  40075d: 	movl   $0x1,-0x20(%rbp) // 将 1 存放到 rbp - 0x20 的位置
  400764: 	movl   $0x2,-0x1c(%rbp) // 依次存放其他值
  40076b: 	movl   $0x3,-0x18(%rbp)
  400772: 	movl   $0x4,-0x14(%rbp)
  400779: 	movl   $0x5,-0x10(%rbp)
  400780: 	lea    -0x20(%rbp),%rax   // 将 rbp - 0x20 的地址存放到 rax ，也就是数组的首地址
  400784: 	mov    $0x5,%esi          // 将 0x5 放到 esi
  400789: 	mov    %rax,%rdi          // 将 rax 中的值放到 rdi，两个传递参数准备就绪
  40078c: 	callq  400710 <_Z3AddPii> // 调用 Add 函数，callq指令会先将返回地址（下一条指令执行的地址：400791）压入到栈中，然后跳转
  400791: 	mov    %eax,-0x4(%rbp)    // Add 函数返回后从这里继续执行，先将函数返回值放到栈中，相当于给变量 sum 赋值
  400794: 	mov    0x2008aa(%rip),%eax        # 601044 <_ZZ4mainE3num> // 将静态变量 num 的值放到 eax
  40079a: 	add    %eax,-0x4(%rbp)    // 将 eax 和变量 sum 相加，并存放到 sum 中
  40079d: 	mov    -0x4(%rbp),%eax    // 将 sum 作为返回值放到 eax
  4007a0: 	leaveq                    // 将 rsp 指向 rbp，然后弹出栈上保存的上一个栈帧的地址到 rbp 
  4007a1: 	retq                      // 函数返回，retq指令会从栈中弹出返回地址到指令指针寄存器 rip 中

#if 0

/*
 * intel
 */
0000000000001149 <Add>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	48 89 7d e8          	mov    %rdi,-0x18(%rbp)	// (rbp-0x18)=rdi
    1155:	89 75 e4             	mov    %esi,-0x1c(%rbp)	// (rbp-0x1c)=esi
    1158:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%rbp)	// (rbp-0x8)=0
    115f:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)	// (rbp-0x4)=0
    1166:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)	// (rbp-0x4)=0
    116d:	eb 1d                	jmp    118c <Add+0x43>	// jump
    116f:	8b 45 fc             	mov    -0x4(%rbp),%eax	// eax=(rbp-0x4)
    1172:	48 98                	cltq   
    1174:	48 8d 14 85 00 00 00 	lea    0x0(,%rax,4),%rdx	// rdx=(rax*4)+0
    117b:	00 
    117c:	48 8b 45 e8          	mov    -0x18(%rbp),%rax	// rax=(rbp-0x18)
    1180:	48 01 d0             	add    %rdx,%rax	// rax=rax+rdx
    1183:	8b 00                	mov    (%rax),%eax	// eax=(rax)
    1185:	01 45 f8             	add    %eax,-0x8(%rbp)	// (rbp-0x8)+=eax
    1188:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)	// (rbp-0x4)+=1
    118c:	8b 45 fc             	mov    -0x4(%rbp),%eax	// eax=(rbp-0x4)
    118f:	3b 45 e4             	cmp    -0x1c(%rbp),%eax	// eax-(rbp-0x1c)
    1192:	7c db                	jl     116f <Add+0x26>	// 小于(有符号<)
    1194:	8b 45 f8             	mov    -0x8(%rbp),%eax	// eax=(rbp-0x8)
    1197:	5d                   	pop    %rbp
    1198:	c3                   	retq   

0000000000001199 <main>:
    1199:	f3 0f 1e fa          	endbr64 
    119d:	55                   	push   %rbp
    119e:	48 89 e5             	mov    %rsp,%rbp
    11a1:	48 83 ec 30          	sub    $0x30,%rsp
    11a5:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
    11ac:	00 00 
    11ae:	48 89 45 f8          	mov    %rax,-0x8(%rbp)
    11b2:	31 c0                	xor    %eax,%eax
    11b4:	c7 45 e0 01 00 00 00 	movl   $0x1,-0x20(%rbp)	// (rbp-0x20)=1
    11bb:	c7 45 e4 02 00 00 00 	movl   $0x2,-0x1c(%rbp)	// (rbp-0x1c)=2
    11c2:	c7 45 e8 03 00 00 00 	movl   $0x3,-0x18(%rbp)	// (rbp-0x18)=3
    11c9:	c7 45 ec 04 00 00 00 	movl   $0x4,-0x14(%rbp)	// (rbp-0x14)=4
    11d0:	c7 45 f0 05 00 00 00 	movl   $0x5,-0x10(%rbp)	// (rbp-0x10)=5
    11d7:	48 8d 45 e0          	lea    -0x20(%rbp),%rax	// rax=(rbp-0x20)
    11db:	be 05 00 00 00       	mov    $0x5,%esi	// esi=5
    11e0:	48 89 c7             	mov    %rax,%rdi	// rdi=rax
    11e3:	e8 61 ff ff ff       	callq  1149 <Add>	// add(rdi, esi)
    11e8:	89 45 dc             	mov    %eax,-0x24(%rbp)	// (rbp-0x24)=eax
    11eb:	8b 05 1f 2e 00 00    	mov    0x2e1f(%rip),%eax        # 4010 <num.2324> eax=rip+0x2e1f
    11f1:	01 45 dc             	add    %eax,-0x24(%rbp)	// (rbp-0x24)=eax
    11f4:	8b 45 dc             	mov    -0x24(%rbp),%eax	// eax=(rbp-0x24)
    11f7:	48 8b 55 f8          	mov    -0x8(%rbp),%rdx	// rdx=(rbp-0x8)
    11fb:	64 48 33 14 25 28 00 	xor    %fs:0x28,%rdx
    1202:	00 00 
    1204:	74 05                	je     120b <main+0x72>
    1206:	e8 45 fe ff ff       	callq  1050 <__stack_chk_fail@plt>
    120b:	c9                   	leaveq 
    120c:	c3                   	retq   
    120d:	0f 1f 00             	nopl   (%rax)


/*
 * arm
 */
000000000040051c <Add>:
  40051c:	d10083ff 	sub	sp, sp, #0x20
  400520:	f90007e0 	str	x0, [sp, #8]	// [sp+8]=x0
  400524:	b90007e1 	str	w1, [sp, #4]	// [sp+4]=w1
  400528:	b9001fff 	str	wzr, [sp, #28]	// [sp+28]=0
  40052c:	b9001bff 	str	wzr, [sp, #24]	// [sp+24]=0
  400530:	b9001bff 	str	wzr, [sp, #24]	// [sp+24]=0
  400534:	1400000c 	b	400564 <Add+0x48>
  400538:	b9801be0 	ldrsw	x0, [sp, #24]	// w0=[sp+24]
  40053c:	d37ef400 	lsl	x0, x0, #2	// x0=x0<<2
  400540:	f94007e1 	ldr	x1, [sp, #8]	// x1=[sp+8]
  400544:	8b000020 	add	x0, x1, x0	// x0=x1+x0
  400548:	b9400000 	ldr	w0, [x0]	// w0=[x0]
  40054c:	b9401fe1 	ldr	w1, [sp, #28]	// w1=[sp+28]
  400550:	0b000020 	add	w0, w1, w0	// w0=w1+w0
  400554:	b9001fe0 	str	w0, [sp, #28]	// [sp+28]=w0
  400558:	b9401be0 	ldr	w0, [sp, #24]	// w0=[sp+24]
  40055c:	11000400 	add	w0, w0, #0x1	// w0=w0+0x1
  400560:	b9001be0 	str	w0, [sp, #24]	// [sp+24]=w0
  400564:	b9401be1 	ldr	w1, [sp, #24]	// w1=[sp+24]
  400568:	b94007e0 	ldr	w0, [sp, #4]	// w0=[sp+4]
  40056c:	6b00003f 	cmp	w1, w0		// w1-w0
  400570:	54fffe4b 	b.lt	400538 <Add+0x1c>  // b.tstop
  400574:	b9401fe0 	ldr	w0, [sp, #28]
  400578:	910083ff 	add	sp, sp, #0x20
  40057c:	d65f03c0 	ret

0000000000400580 <main>:
  400580:	a9bd7bfd 	stp	x29, x30, [sp, #-48]!
  400584:	910003fd 	mov	x29, sp
  400588:	90000000 	adrp	x0, 400000 <_init-0x3b0>
  40058c:	911a4000 	add	x0, x0, #0x690	// x0=400690
  400590:	910063a2 	add	x2, x29, #0x18	// x2=x29+0x18
  400594:	aa0003e3 	mov	x3, x0		// x3=x0
  400598:	a9400460 	ldp	x0, x1, [x3]	// x0=[x3], x1=[x3+8]
  40059c:	a9000440 	stp	x0, x1, [x2]	// [x2]=x0, [x2+8]=x1
  4005a0:	b9401060 	ldr	w0, [x3, #16]	// w0=[x3+16]
  4005a4:	b9001040 	str	w0, [x2, #16]	// [x2+16]=w0
  4005a8:	910063a0 	add	x0, x29, #0x18	// x0=x29+0x18
  4005ac:	528000a1 	mov	w1, #0x5                   	// #5
  4005b0:	97ffffdb 	bl	40051c <Add>	// add(x0, w1)
  4005b4:	b9002fa0 	str	w0, [x29, #44]	// [x29+44]=w0
  4005b8:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  4005bc:	9100a000 	add	x0, x0, #0x28	// r11028
  4005c0:	b9400000 	ldr	w0, [x0]	// w0=[x0]
  4005c4:	b9402fa1 	ldr	w1, [x29, #44]	// w1=[x29+44]
  4005c8:	0b000020 	add	w0, w1, w0	// w=w1+w0
  4005cc:	b9002fa0 	str	w0, [x29, #44]	// [x29+44]=w0
  4005d0:	b9402fa0 	ldr	w0, [x29, #44]	// w0=[x29+44]
  4005d4:	a8c37bfd 	ldp	x29, x30, [sp], #48
  4005d8:	d65f03c0 	ret
  4005dc:	00000000 	.inst	0x00000000 ; undefined

#endif

#endif
